function [Tn, cv] = as10_market(para, entry_sim_tr, fc_x_tr, ...
    dev_profit_all_tr, dev_profit_one_tr,  ...
    ind_para_fc_x, ind_para_sig, ind_para_scope, ind_para_corr, ind_mktsize, N_dev, g_ar_tr,...
    entry_sim_boot, fc_x_boot, dev_profit_all_boot, ...
    dev_profit_one_boot, g_ar_boot, ...
    use_scope, brewer_entry_tr, max_profit_top_vec, min_profit_top_vec, ...
    ind_mktsize_scope, max_profit_top_vec_boot, min_profit_top_vec_boot, ...
    brewer_fc_x_tr, brewer_g_ar_tr, brewer_g_ar_tr_boot, N_brewer_dev, fc_err, ...
    est_corr, entry_dev2, N_dev2, corr_sim, dev2_ind_f1_tr, dev2_ind_f2_tr, corr_g_ar, corr_g_ar_boot,...
    reps, sig_level)
%purpose: compute the moment functions and obtain test statistic and critical value

N_obs = size(entry_sim_tr, 1);
N_boot = size(entry_sim_boot, 2);

if ~isempty(ind_mktsize)
    N_sig = length(ind_mktsize) + 1; % # of std dev parameters
    ind_sig = false(N_obs, N_sig);
    ind_sig(:, 1) = 1 - sum(fc_x_tr(:, ind_mktsize), 2);
    ind_sig(:, 2:end) = fc_x_tr(:, ind_mktsize);
else
    N_sig = 1;
    ind_sig = true(N_obs, 1);
end

% decode the parameters
para_fc_x = reshape(para(ind_para_fc_x), [1 length(ind_para_fc_x)]);
para_sig = reshape(para(ind_para_sig), [1 length(ind_para_sig)]);

if length(para_sig)~=size(ind_sig, 2)
    error('inconsistent parameter values and market size indices');
end

if use_scope
    para_scope = para(ind_para_scope);
    scope_x = [1 - sum(fc_x_tr(:, ind_mktsize_scope), 2), fc_x_tr(:, ind_mktsize_scope)]*para_scope(:); % get mktsize-specific scope parameter
    scope_x_lb = (scope_x<0).*(scope_x);
    scope_x_ub = (scope_x>0).*(scope_x);
else
    scope_x_lb = 0;
    scope_x_ub = 0;
end

% moment functions
lb_y = dev_profit_all_tr + fc_x_tr*para_fc_x(:) + scope_x_lb; 
ub_y = dev_profit_one_tr + fc_x_tr*para_fc_x(:) + scope_x_ub;

if est_corr    
    lb_y = lb_y + para(ind_para_corr)*corr_sim; %N_dev*N_mkt x 1 x 1 x 1 x N_corr_sim
    ub_y = ub_y + para(ind_para_corr)*corr_sim;
end

sig = ind_sig*para_sig(:);

p_lb = normcdf(lb_y./sig);
p_ub = normcdf(ub_y./sig);

lb_g = mean(p_lb, 5) - entry_sim_tr;%when ~est_corr, mean(p_lb,5) does nothing. Otherwise, it takes avg across market-specific fc shock draws
ub_g = entry_sim_tr - mean(p_ub, 5);

m = [lb_g, ub_g]; %N_dev*N_mkt x 1

% whether to compute the critical value as well as the test statistic
if ~isempty(entry_sim_boot)
    lb_y_boot = dev_profit_all_boot ...
        + squeeze(sum(fc_x_boot.*para_fc_x, 2));
    ub_y_boot = dev_profit_one_boot ...
        + squeeze(sum(fc_x_boot.*para_fc_x, 2));

    if est_corr
        lb_y_boot = lb_y_boot + para(ind_para_corr)*corr_sim;
        ub_y_boot = ub_y_boot + para(ind_para_corr)*corr_sim;
    end

    p_lb_boot = normcdf(lb_y_boot./sig); %n_obs x n_boot
    p_ub_boot = normcdf(ub_y_boot./sig);

    lb_g_boot = mean(p_lb_boot, 5) - entry_sim_boot;
    ub_g_boot = entry_sim_boot - mean(p_ub_boot, 5);

    m_boot = nan(N_obs, 2, N_boot);
    m_boot(:, 1, :) = lb_g_boot;
    m_boot(:, 2, :) = ub_g_boot;
else
    m_boot = [];
end

if use_scope 

    % per product FC, which is the same for all products within a brewer
    brewer_fc = brewer_fc_x_tr*para_fc_x(:);

    % scope parameters
    brewer_scope_x = [1 - sum(brewer_fc_x_tr(:, ind_mktsize_scope), 2), ...
        brewer_fc_x_tr(:, ind_mktsize_scope)]*para_scope(:);

    % simulate the probability bounds
    N_brewer_obs = size(brewer_fc, 1); % # of brewer/mkt combinations = N_mkt*N_brewer_dev

    if ~isempty(ind_mktsize)
        brewer_ind_sig = false(N_brewer_obs, N_sig);
        brewer_ind_sig(:, 1) = 1 - sum(brewer_fc_x_tr(:, ind_mktsize), 2);
        brewer_ind_sig(:, 2:N_sig) = brewer_fc_x_tr(:, ind_mktsize);
    else
        brewer_ind_sig = true(N_brewer_obs, 1);
    end

    [brewer_prob_ub, brewer_prob_lb] = ...
        sim_brewer_entry(max_profit_top_vec, min_profit_top_vec, brewer_fc,...
        brewer_ind_sig, para(ind_para_sig), brewer_scope_x, fc_err);
    
    lb_g = brewer_prob_lb - brewer_entry_tr;
    ub_g = brewer_entry_tr - brewer_prob_ub;

    brewer_m = [lb_g, ub_g];

    if ~isempty(max_profit_top_vec_boot) && ~isempty(min_profit_top_vec_boot)
        [brewer_prob_ub_boot, brewer_prob_lb_boot] = ...
            sim_brewer_entry(max_profit_top_vec_boot, min_profit_top_vec_boot, brewer_fc,...
            brewer_ind_sig, para(ind_para_sig), brewer_scope_x, fc_err);
        brewer_m_boot = nan(N_brewer_obs, 2, N_boot);
        brewer_m_boot(:, 1, :) = brewer_prob_lb_boot - brewer_entry_tr;
        brewer_m_boot(:, 2, :) = brewer_entry_tr - brewer_prob_ub_boot;
    else
        m_boot = [];
        brewer_m_boot = [];
        brewer_g_ar_tr_boot = [];
    end
else    
    brewer_m = [];
    brewer_m_boot = [];
    brewer_g_ar_tr_boot = [];
end

if est_corr    
    % prob bounds   
    p_ub2 = mean(p_ub(dev2_ind_f1_tr, :, :, :, :).*p_ub(dev2_ind_f2_tr, :, :, :, :), 5);
    p_lb2 = mean(p_lb(dev2_ind_f1_tr, :, :, :, :).*p_lb(dev2_ind_f2_tr, :, :, :, :), 5);
    corr_m = [p_lb2 - entry_dev2, entry_dev2 - p_ub2];

    if ~isempty(corr_g_ar_boot)
        corr_m_boot = nan(size(corr_m, 1), 2, N_boot);
        for nb = 1 : N_boot
            p_lb_boot_nb = p_lb_boot(:, nb, :, :, :);
            p_ub_boot_nb = p_ub_boot(:, nb, :, :, :);
            corr_m_boot(:, 1, nb) = mean(p_lb_boot_nb(dev2_ind_f1_tr, :, :, :, :)...
                .*p_lb_boot_nb(dev2_ind_f2_tr, :, :, :, :), 5) - entry_dev2;
            corr_m_boot(:, 2, nb) = entry_dev2 - mean(p_ub_boot_nb(dev2_ind_f1_tr, :, :, :, :)...
                .*p_ub_boot_nb(dev2_ind_f2_tr, :, :, :, :), 5);
        end
    else
        corr_m_boot = [];
    end
else
    corr_m = [];
    corr_m_boot = [];
end

try
    [Tn, cv] = as10_test_market_corr(m, N_dev, m_boot, g_ar_tr, g_ar_boot, ...
        use_scope, brewer_m, N_brewer_dev, brewer_m_boot, brewer_g_ar_tr, brewer_g_ar_tr_boot,...
        est_corr, corr_m, N_dev2, corr_m_boot, corr_g_ar, corr_g_ar_boot, ...
        N_boot, reps, sig_level);
catch
    Tn = Inf;
    cv = 0;
end

